use strict;
use warnings;
use XML::Bare;

main();

sub help {
    print "Usage:\n";
    print "perl -w Build.pl SOURCE_FOLDER\n";
    print "SOURCE_FOLDER: contain source code\n";

    exit(1);
}

sub main {
    help() if not defined $ARGV[0];

    my $sourceFolder = $ARGV[0];
    my $makefileOrignal = "Makefile.orignal";
    my $makefile = "Makefile";
    my $algorithmFile = "AlgorithmList";
    my @algorithms;

    # Parse Algorithm list file
    open A_FILE, $sourceFolder . "/" . $algorithmFile
        or die "Can't open algorithm file $sourceFolder/$algorithmFile\n";
    my $line = 1;
    foreach (<A_FILE>) {
        next if /^\s*#/;
        if(/^\s*(\w+):(\w+)/) {
            print "Find algorithm $1, source file $2.cc, header file $2.h\n";
            die "Can't find file $sourceFolder/$2.cc\n" if not -e "$sourceFolder/$2.cc";
            die "Can't find file $sourceFolder/$2.h\n" if not -e "$sourceFolder/$2.h";
            push @algorithms, {algorithm=>$1, file=>$2};
        }
        else {
            die "Error format in $sourceFolder/$algorithmFile line: $line\n";
        }
        $line++;
    }
    close A_FILE;

    # Update Makefile
    print "Reading $sourceFolder/$makefileOrignal";
    open O_FILE, $sourceFolder . "/" . $makefileOrignal
        or die "Can't open file $sourceFolder/$makefileOrignal\n";
    my @makeFileLines = <O_FILE>;
    close O_FILE;

    print "Update $sourceFolder/$makefile...\n";
    open M_FILE, ">" . $sourceFolder . "/" . $makefile
        or die "Can't open file $sourceFolder/$makefile\n";
    my $insertPoint = "# Clean the build files";
    my $isInsert = 0;
    foreach my $line (@makeFileLines) {
        if($line =~ /$insertPoint/) {
            foreach my $alg (@algorithms) {
                print M_FILE "$alg->{file}.o: \$(SRC_DIR)/$alg->{file}.cc \$(SRC_DIR)/$alg->{file}.h\n";
                print M_FILE "\t\$(COMPILER) -I \$(LIB_DIR)/ -c \$(SRC_DIR)/$alg->{file}.cc -o \$(OBJ_DIR)/$alg->{file}.o\n\n";
            }
            $isInsert = 1;
        }
        elsif($line =~ /(TARGET_FILES = .*)/) {
            chomp $line;
            $line .= " $_->{file}.o" foreach @algorithms;
            $line .= "\n";
        }
        elsif($line =~ /(OBJECT_FILES = .*)/) {
            chomp $line;
            $line .= " \$(OBJ_DIR)/$_->{file}.o" foreach @algorithms;
            $line .= "\n";
        }
        print M_FILE $line;
    }
    close M_FILE;
}
